<?php

/**
 * Фильтр структуры фронтенда. Определяет активный пункт меню.
 *
 */
class Frontend_Filter_Structure extends Kernel_Filter
{
    
    /**
     * Наименования сквозных GET-параметров бэкенда.
     *
     * @var array
     */
    static private $params = array(
        'section' => null,
        'module'  => null,
        'manager' => null,
        'token'   => null,
    );

    /**
     * Возвращает значение сквозного параметра.
     *
     * @param   string  $param
     * @return  mixed
     */
    static public function get($param) {
        return get_array_element(self::$params, $param);
    }

    /**
     * Устанавливает значение сквозного параметра.
     *
     * @param   string  $param
     * @param   mixed   $value
     */
    static public function set($param, $value) {
        self::$params[$param] = $value;
    }

    /**
     * Возвращает наименования сквозных параметров.
     * :KLUDGE: надо убрать куда-то, т.к. используется только для менеджеров.
     *
     * @return  array
     */
    static public function params() {
        return array_keys(self::$params);
    }

    /**
     * Массив секций бэкенда.
     *
     * @var array
     */
    public static $sections = array();

    /**
     * Массив менеджеров текущей секции.
     *
     * @var array
     */
    public static $managers = array();
    
    /**
     * Массив токенов текущего менеджера.
     *
     * @var array
     */
    public static $tokens = array();

    /**
     * Запускает фильтр 
     *
     */
    public function process() {
        parent::process();
        $request = Application::getRequest();

        // загружаем секции админки
        self::$sections = $this->_getSections();
        // выставляем идентификатор активной секции
        self::set('section', $request->get('section', key(self::$sections)));
        // проверяем, существует ли выбранная секция
        if (!array_key_exists(self::get('section'), self::$sections)) {
            $this->_abort('Section not found');
        }
        
        // загружаем менеджеры админки, соответствующие текущей секции
        self::$managers = $this->_getManagers();
        // проверяем, есть ли менеджеры в выбранной секции
        if (empty(self::$managers)) {
            $this->_abort('Section is empty');
        }
        $module = $request->get('module');
        $manager = $request->get('manager');
        // если менеджер не указан, выбираем первый по списку
        if (empty($module) && empty($manager)) {
            list($module, $manager) = current(self::$managers);
        // проверяем, присутствует ли менеджер в текущей секции… некрасиво
        // как-то, но вводить лишний первичный ключ как-то тоже неохота
        } elseif (false === array_search(array($module, $manager), self::$managers)) {
            $this->_abort('Manager not found in section');
        }
        self::set('module', $module);
        self::set('manager', $manager);
        
        /*self::$tokens = $this->_getManagerTokens();
        if (count(self::$tokens)) {
            $token = $request->get('token');
            if (empty($token)) {
                $token = self::$tokens[0];
            } elseif (false === array_search($token, self::$tokens)) {
                $this->_abort('Manager has no such token');
            }
            self::set('token', $token);
        }*/
        
        // эти параметры должны передаваться во все ссылки бэкенда
        Application::getResponse()->assign('through_default', implode(',', self::params()));
    }

    /**
     * Перекрываем метод, т.к. секции для фронтенда распологаются 
     * в таблице frontend_section
     *
     * @return  array
     */
    private function _getSections() 
    {
        $query = 'SELECT
                         `id`, `name`
                    FROM
                         `frontend_section`
                ORDER BY
                         `position`';
        return database::fetchPairs($query);
    }

    /**
     * Возвращает наименование класса компонента, который обработает запрошенное
     * действие.
     * 
     * Перекрываем метод, 
     * т.к. компоненты для фронтенда находятся в таблице frontend_manager
     *
     * @return  string
     */
    private function _getManagers() 
    {
        $query = 'SELECT
                         `module`,
                         `name`
                    FROM
                         `frontend_manager`
                   WHERE
                         `section_id` = ' . (int)self::get('section') . '
                ORDER BY
                         `position`';
        return array_map('array_values', database::fetchAll($query));
    }
    
    private function _getManagerTokens() 
    {
        $query = '
            SELECT 
                   `name`
              FROM
                   `frontend_manager_token` 
             WHERE 
                   `manager_id`  = (SELECT 
                                           `id` 
                                      FROM 
                                           `frontend_manager` 
                                     WHERE 
                                           `module` = "' .self::get('module') . '")
         ORDER BY
                   `position`';
        return database::fetchCol($query);
    }
    
}
